/**
 * Copyright (c) Software Institute of PKU
 * All rights reserved. 
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */
package edu.pku.sei.modeler.model.structure;

import org.eclipse.draw2d.geometry.Rectangle;
import org.w3c.dom.Element;

import edu.pku.sei.modeler.model.xml.XMLUtility;

/**
 * @author zl
 *
 */
public class PinLocatorAdapter extends AbstractLocator {
	private int size = 15;
	
	public void setSize(int size) {
		this.size = size;
	}
	/* (non-Javadoc)
	 * @see edu.pku.sei.modeler.model.structure.AbstractLocator#getNewBound(int, org.eclipse.draw2d.geometry.Rectangle)
	 */
	@Override
	public Rectangle getNewBound(int index, Rectangle oldBound) {
		oldBound.width = 15;
		oldBound.height = 15;
		if(!parentBound.equals(oldParentBound) && oldParentBound != null) {
			int xDistance = parentBound.x - oldParentBound.x;
			int yDistance = parentBound.y - oldParentBound.y;
			
			oldBound.x = oldBound.x + xDistance;
			oldBound.y = oldBound.y + yDistance;
		}
		int top = parentBound.y;
		int bottom = parentBound.y + parentBound.height;
		int left = parentBound.x;
		int right = parentBound.x + parentBound.width;
		/**
		 * the diagram is divided into 9 areas by the parent square, as shown below:
		 * 
		 *           |          |
		 *        8  |     5    |  9
		 *     ------|----------|------
		 *           |          |
		 *        4  |     1    |  2
		 *           |          |
		 *     ------|----------|------
		 *        7  |     3    |  6
		 *           |          |
		 */
		// child node is located in area 1:
		if(parentBound.contains(oldBound)) {
			oldBound.x = right;
		}
		// area 2:
		else if(oldBound.x >= right
				&& oldBound.y > top
				&& oldBound.y + oldBound.height < bottom) {
			oldBound.x = right;
		}
		// area 3:
		else if(oldBound.y >= bottom
				&& oldBound.x > left
				&& oldBound.x + oldBound.width < right) {
			oldBound.y = bottom;
		}
		// area 4:
		else if(oldBound.x + oldBound.width <= left
				&& oldBound.y > top
				&& oldBound.y + oldBound.height < bottom) {
			oldBound.x = left - oldBound.width;
		}
		// area 5:
		else if(oldBound.y + oldBound.height <= top
				&& oldBound.x > left
				&& oldBound.x + oldBound.width < right) {
			oldBound.y = top - oldBound.height;
		}
		// area 6:
		else if(oldBound.x > right
				&& oldBound.y > bottom) {
			oldBound.x = right;
			oldBound.y = (top + bottom - oldBound.height)/2; 
		}
		// area 7:
		else if(oldBound.y > bottom
				&& oldBound.x + oldBound.width < left) {
			oldBound.x = left - oldBound.width;
			oldBound.y = (top + bottom - oldBound.height)/2;
		}
		// area 8:
		else if(oldBound.x + oldBound.width < left
				&& oldBound.y + oldBound.height < top) {
			oldBound.x = left - oldBound.width;
			oldBound.y = (top + bottom - oldBound.height)/2;
		}
		// area 9:
		else if(oldBound.x > right
				&& oldBound.y + oldBound.height < top) {
			oldBound.x = right;
			oldBound.y = (top + bottom - oldBound.height)/2;
		}
		// beyond all these situations:
		else {
			oldBound.x = right;
			oldBound.y = (top + bottom - oldBound.height)/2;
		}
		return oldBound;
	}

	/* (non-Javadoc)
	 * @see edu.pku.sei.modeler.model.structure.AbstractLocator#getType()
	 */
	@Override
	public String getType() {
		return StructurePackage.__PINLOCATORADAPTER__;
	}

	public void serialize(Element root) {
		super.serialize(root);
		XMLUtility.xmlInstance.serializeAttribute(root, StructurePackage.PINLOCATOR_SIZE, size);
	}
	
	public void deSerialize(Element root) {
		super.deSerialize(root);
		size = XMLUtility.xmlInstance.deSerializeInt(root, StructurePackage.PINLOCATOR_SIZE);
	}
	/**
	 * @return the size
	 */
	public int getSize() {
		return size;
	}
}
